package com.zaodei.rxjob.job.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.zaodei.rxjob.common.annotation.Log;
import com.zaodei.rxjob.common.base.AjaxResult;
import com.zaodei.rxjob.common.enums.BusinessType;
import com.zaodei.rxjob.common.page.TableDataInfo;
import com.zaodei.rxjob.common.support.Convert;
import com.zaodei.rxjob.core.util.ShiroUtils;
import com.zaodei.rxjob.core.web.base.BaseController;
import com.zaodei.rxjob.job.admin.core.conf.XxlJobAdminConfig;
import com.zaodei.rxjob.job.admin.core.model.JobGroupProject;
import com.zaodei.rxjob.job.admin.core.model.XxlJobGroup;
import com.zaodei.rxjob.job.admin.core.model.XxlJobRegistry;
import com.zaodei.rxjob.job.admin.core.util.I18nUtil;
import com.xxl.job.core.enums.RegistryConfig;
import com.zaodei.rxjob.job.dao.ProjectJobGroupdao;
import com.zaodei.rxjob.job.dao.XxlJobGroupDao;
import com.zaodei.rxjob.job.dao.XxlJobInfoDao;

/**
 * @Title:执行器
 * @Description: 待执行服务地址
 * @Author:wuche@laozo.com
 * @time:2019年1月19日
 */
@Controller
@RequestMapping("/job/jobgroup")
public class NjobGroupController extends BaseController {
	private String prefix = "job/jobgroup";
	@Resource
	public XxlJobInfoDao xxlJobInfoDao;
	@Resource
	public XxlJobGroupDao xxlJobGroupDao;
	@Resource
	private ProjectJobGroupdao projectJobGroupdao;

	@RequiresPermissions("job:jobgroup:view")
	@RequestMapping
	public String index(Model model) {
		return prefix + "/jobgroup";
	}

	@RequiresPermissions("job:jobgroup:list")
	@RequestMapping("/list")
	@ResponseBody
	public TableDataInfo list(XxlJobGroup jobGroup) {
		// job group (executor)
	//	List<XxlJobGroup> list = xxlJobGroupDao.findAll();
		jobGroup.setUserId(ShiroUtils.getUserId());
		List<XxlJobGroup> list = xxlJobGroupDao.selectJobGroupList(jobGroup);
		return getDataTable(list);
	}

	/**
	 * 新增调度器
	 */
	@RequiresPermissions("job:jobgroup:add")
	@GetMapping("/add")
	public String add(ModelMap model) {
		return prefix + "/add";
	}

	@RequiresPermissions("job:jobgroup:add")
	@Log(title = "新增调度器", businessType = BusinessType.INSERT)
	@RequestMapping("/add")
	@ResponseBody
	public AjaxResult add(XxlJobGroup xxlJobGroup) {
	    // valid
	    if (xxlJobGroup.getAppName()==null || StringUtils.isBlank(xxlJobGroup.getAppName())) {
	     return error((I18nUtil.getString("system_please_input")+"AppName") );
	    }
	    if (xxlJobGroup.getAppName().length()<4 || xxlJobGroup.getAppName().length()>64) {
	     return error(I18nUtil.getString("jobgroup_field_appName_length") );
	    }
	    if (xxlJobGroup.getTitle()==null || StringUtils.isBlank(xxlJobGroup.getTitle())) {
	     return error((I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")) );
	    }
	    if (xxlJobGroup.getAddressType()!=0) {
	     if (StringUtils.isBlank(xxlJobGroup.getAddressList())) {
	      return error(I18nUtil.getString("jobgroup_field_addressType_limit") );
	     }
	     String[] addresss = xxlJobGroup.getAddressList().split(",");
	     for (String item: addresss) {
	      if (StringUtils.isBlank(item)) {
	       return error(I18nUtil.getString("jobgroup_field_registryList_unvalid") );
	      }
	     }
	    }
	    int ret = xxlJobGroupDao.save(xxlJobGroup);
	    //新增项目-执行器
	    if(ret>0){
	    	JobGroupProject jobGroupProject = new JobGroupProject();
	    	jobGroupProject.setProjectId(xxlJobGroup.getProjectId());
	    	jobGroupProject.setJobGroup(xxlJobGroup.getId());
	    	projectJobGroupdao.insertProjectJobGroup(jobGroupProject);
	    }
	    return (ret>0)?toAjax(true):toAjax(false);
	}

	/**
	 * 更新执行器
	 */
	@RequiresPermissions("job:jobgroup:edit")
	@GetMapping("/edit/{id}")
	public String edit(ModelMap mmap,@PathVariable("id") int id) {
		XxlJobGroup jobGroup = xxlJobGroupDao.load(id);
		JobGroupProject jobGroupProject = projectJobGroupdao.selectProjectJobGroup(id);
		jobGroup.setProjectId(jobGroupProject.getProjectId());
		mmap.put("jobGroup", jobGroup);
		return prefix + "/edit";
	}

	@RequiresPermissions("job:jobgroup:edit")
	@RequestMapping("/edit")
	@Log(title = "更新执行器", businessType = BusinessType.UPDATE)
	@ResponseBody
	public AjaxResult edit(XxlJobGroup xxlJobGroup) {
		// 添加操作控制
		if (!isOptJobGroup(xxlJobGroup.getId())) {
			return error("观察者没有操作权限");
		}
	 // valid
	    if (xxlJobGroup.getAppName()==null || StringUtils.isBlank(xxlJobGroup.getAppName())) {
	     return error((I18nUtil.getString("system_please_input")+"AppName") );
	    }
	    if (xxlJobGroup.getAppName().length()<4 || xxlJobGroup.getAppName().length()>64) {
	     return error(I18nUtil.getString("jobgroup_field_appName_length") );
	    }
	    if (xxlJobGroup.getTitle()==null || StringUtils.isBlank(xxlJobGroup.getTitle())) {
	     return error((I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")) );
	    }
	    if (xxlJobGroup.getAddressType() == 0) {
	     // 0=自动注册
	     List<String> registryList = findRegistryByAppName(xxlJobGroup.getAppName());
	     String addressListStr = null;
	     if (CollectionUtils.isNotEmpty(registryList)) {
	      Collections.sort(registryList);
	      addressListStr = StringUtils.join(registryList, ",");
	     }
	     xxlJobGroup.setAddressList(addressListStr);
	    } else {
	     // 1=手动录入
	     if (StringUtils.isBlank(xxlJobGroup.getAddressList())) {
	      return error(I18nUtil.getString("jobgroup_field_addressType_limit") );
	     }
	     String[] addresss = xxlJobGroup.getAddressList().split(",");
	     for (String item: addresss) {
	      if (StringUtils.isBlank(item)) {
	       return error(I18nUtil.getString("jobgroup_field_registryList_unvalid") );
	      }
	     }
	    }

	    int ret = xxlJobGroupDao.update(xxlJobGroup);
	    if(ret>0){
	    	JobGroupProject jobGroupProject = new JobGroupProject();
	    	jobGroupProject.setProjectId(xxlJobGroup.getProjectId());
	    	jobGroupProject.setJobGroup(xxlJobGroup.getId());
	    	projectJobGroupdao.deleteProjectJobGroup(jobGroupProject);
	    	projectJobGroupdao.insertProjectJobGroup(jobGroupProject);
	    }
	    return (ret>0)?toAjax(true):toAjax(false);
	}
	
	private List<String> findRegistryByAppName(String appNameParam){
	    HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
	    List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT);
	    if (list != null) {
	     for (XxlJobRegistry item: list) {
	      if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
	       String appName = item.getRegistryKey();
	       List<String> registryList = appAddressMap.get(appName);
	       if (registryList == null) {
	        registryList = new ArrayList<String>();
	       }

	       if (!registryList.contains(item.getRegistryValue())) {
	        registryList.add(item.getRegistryValue());
	       }
	       appAddressMap.put(appName, registryList);
	      }
	     }
	    }
	    return appAddressMap.get(appNameParam);
	   }

	@RequiresPermissions("job:jobgroup:remove")
	@RequestMapping("/remove")
	@Log(title = "删除执行器", businessType = BusinessType.DELETE)
	@ResponseBody
	public AjaxResult remove(String ids) {
		// valid
		String idsArray [] = ids.split(",");
		for (int i = 0; i < idsArray.length; i++) {
			String idStr = idsArray[i];
			if(StringUtils.isNotBlank(idStr)){
				int id = Integer.parseInt(idStr);
				if (!isOptJobGroup(id)) {
					return error("观察者没有操作权限");
				}
				int count = xxlJobInfoDao.pageListCount(0, 10, id, null, null);
				if (count > 0) {
					return error(I18nUtil.getString("jobgroup_del_limit_0"));
				}
			}
		}
		List<XxlJobGroup> allList = xxlJobGroupDao.findAll();
		if (allList.size() == 1) {
			return error(I18nUtil.getString("jobgroup_del_limit_1"));
		}
        int  ret = xxlJobGroupDao.removeMore(Convert.toIntArray(ids));
        if(ret>0){
        	 projectJobGroupdao.removeMoreProjectJobGroup(Convert.toIntArray(ids));
        }
		return (ret>0)?toAjax(true):toAjax(false);
	}
	
	// 判断用户是否可以进行操作
	private boolean isOptJobGroup(int id) {
		JobGroupProject jobGroupProject = new JobGroupProject();
		jobGroupProject.setJobGroup(id);
		jobGroupProject.setUserId(ShiroUtils.getUserId());
		jobGroupProject = projectJobGroupdao.selectProjectJobGroupUser(jobGroupProject);
		Long roleId = jobGroupProject.getRoleId();
		boolean isOpt = false;
		if (6 == roleId || 4 == roleId) {
			isOpt = true;
		}
		return isOpt;
	}
}
